<?php
namespace app\controllers;
use Yii;
use yii\db\Query;
use yii\helpers\ArrayHelper;
use yii\helpers\Url;
use yii\helpers\VarDumper;
use yii\web\NotFoundHttpException;
use yii\web\UploadedFile;

class CampaignController extends BaseController
{
    /**
     * 批量外呼任务
     * @return string|\yii\web\Response
     */
    public function actionIndex()
    {
        if (Yii::$app->request->isAjax){
            $db = (new Query())->from('campaign');
            $count = $db->count('id',$this->callcenter_db);

            $page = Yii::$app->request->get('page',1);
            $limit = Yii::$app->request->get('limit',10);
            $data = $db->offset(($page-1)*$limit)->limit($limit)->orderBy('id desc')->all($this->callcenter_db);
            foreach ($data as &$d){
                $d['calls_url'] = Url::to(['calls','id'=>$d['id']]);
                $d['import_url'] = Url::to(['import','id'=>$d['id']]);
                $d['destroy_url'] = Url::to(['destroy']);
                $d['status_name'] = Yii::$app->params['estatus'][$d['estatus']];
                $d['datetime'] = $d['datetime_init'].' - '.$d['datetime_end'];
                $d['daytime'] = $d['daytime_init'].' - '.$d['daytime_end'];
            }
            return $this->asJson([
                'code' => 0,
                'msg' => '请求成功',
                'count' => $count,
                'data' => $data
            ]);
        }
        return $this->render('index');
    }

    /**
     * 添加呼出任务
     * @return string|\yii\web\Response
     */
    public function actionCreate()
    {
        if (Yii::$app->request->isPost){
            $data = Yii::$app->request->post();
            $campaignid = (new Query())->from('campaign')->max('id',$this->callcenter_db);
            $userfield = (new Query())->from('cdr')->max('userfield',$this->cdr_db);
            if ($campaignid<$userfield){
                $campaignid = $userfield;
            }
            $campaignid++;
            $db = $this->callcenter_db;
            $transaction = $db->beginTransaction();
            try{
                //写入campaign表
                $daytime = explode("-",$data['daytime']);
                $db->createCommand()->insert('campaign',[
                    'id' => $campaignid,
                    'name' => $data['name'],
                    'datetime_init' => $data['datetime_init'],
                    'datetime_end' => $data['datetime_end'],
                    'daytime_init' => trim($daytime[0]),
                    'daytime_end' => trim($daytime[1]),
                    'retries' => $data['retries'],
                    'trunk' => $data['trunk'],
                    'queue' => $data['queue'],
                    'max_canales' => $data['max_canales'],
                    'context' => 'from-internal',
                    'estatus' => 'I',
                    'script' => '<style type="text/css">body{background: #FFF;}</style><style type="text/css">body {background: #FFF;}</style>',
                ])->execute();
                //写入campaign_form表
                $db->createCommand()->insert('campaign_form',[
                    'id_form' => $data['form'],
                    'id_campaign' => $campaignid,
                ])->execute();
                $transaction->commit();
                return $this->asJson(['code'=>0,'msg'=>'添加成功']);
            }catch (\Exception $exception){
                $transaction->rollBack();
                return $this->asJson(['code'=>1,'msg'=>'添加失败','data'=>$exception->getMessage()]);
            }
        }
        $trunks = (new Query())->from('trunks')->all($this->asterisk_db);
        $queues = (new Query())->from('queues_config')->all($this->asterisk_db);
        $forms  = (new Query())->from('form')->all($this->callcenter_db);
        return $this->render('create',['trunks'=>$trunks,'queues'=>$queues,'forms'=>$forms]);
    }

    /**
     * 更新并发
     * @return \yii\web\Response
     */
    public function actionEdit()
    {
        $id = Yii::$app->request->post('id');
        $column_name = Yii::$app->request->post('column_name');
        $column_value = Yii::$app->request->post('column_value');
        $campaign = (new Query())->from('campaign')->where(['id'=>$id])->one($this->callcenter_db);
        if ($campaign==false){
            return $this->asJson(['code'=>1,'msg'=>'任务不存在']);
        }
        try{
            $this->callcenter_db->createCommand()->update('campaign',[$column_name=>$column_value],['id'=>$id])->execute();
            return $this->asJson(['code'=>0,'msg'=>'更新成功']);
        }catch (\Exception $exception){
            return $this->asJson(['code'=>1,'msg'=>'更新失败']);
        }
    }
    
    /**
     * 激活、禁用任务
     * @return \yii\web\Response
     */
    public function actionStatus()
    {
        $ids = Yii::$app->request->post('ids');
        $estatus = Yii::$app->request->post('estatus');
        if (empty($ids) || !is_array($ids) ){
            return $this->asJson(['code'=>1,'msg'=>'请选择操作项']);
        }
        //如果是激活任务则判断是否有导入号码，没有导入号码禁止激活
        if ($estatus=='A'){
            $calls = (new Query())->from('calls')->where(['id_campaign'=>$ids[0]])->count('id',$this->callcenter_db);
            if (!$calls){
                return $this->asJson(['code'=>1,'msg'=>'请先导入号码再激活']);
            }
        }
        if ($this->callcenter_db->createCommand()->update('campaign',['estatus'=>$estatus],['id'=>$ids])->execute()){
            return $this->asJson(['code'=>0,'msg'=>'操作成功']);
        }
        return $this->asJson(['code'=>1,'msg'=>'操作失败']);
    }

    /**
     * 导入号码
     * @return \yii\web\Response
     */
    public function actionImport()
    {
        set_time_limit(0);
        $campaignid = Yii::$app->request->get('id');
        //判断是否已经导入过号码
        $calls = (new Query())->from('calls')->where(['id_campaign'=>$campaignid])->count('id',$this->callcenter_db);
        if ($calls>0){
            return $this->asJson(['code'=>1,'msg'=>'该任务已经导入过号码']);
        }

        $file = UploadedFile::getInstanceByName('file');
        $path = 'uploadfile/';
        $fileName = time().uniqid();
        $ext = $file->getExtension();
        if (!file_exists($path)) {
            mkdir($path, 0755, true);
        }
        $fullName = $path.$fileName.'.'.$ext;
        if($file->saveAs($fullName)) {
            //文件内容读取
            $data = [];
            try{
                $fp = fopen($fullName,"r");
                while(!feof($fp))
                {
                    $line = fgetcsv($fp);
                    if ($line){
                        foreach ($line as $phone){
                            array_push($data,$phone);
                        }
                    }
                }
                fclose($fp);
                //去重,去空
                $data = array_filter(array_unique($data));
            }catch (\Exception $exception){
                return $this->asJson(['code'=>1,'msg'=>'读取文件内容错误','data'=>$exception->getMessage()]);
            }

            //写入数据库
            if (!empty($data)){
                $db = $this->callcenter_db;
                //设置mysql的max_allowed_packet为500M = 1024*1024*500 防止sql过大mysql报错
                $db->createCommand("set global max_allowed_packet=524288000")->execute();
                $transaction = $db->beginTransaction();
                $column = ['id_campaign','phone','retries','dnc','scheduled'];
                $column_data = [];
                foreach ($data as $d){
                    array_push($column_data,[$campaignid,$d,0,0,0]);
                }
                try{
                    $db->createCommand()->batchInsert('calls',$column,$column_data)->execute();
                    $transaction->commit();
                    //导入完成后删除上传的文件
                    unlink($fullName);
                    return $this->asJson(['code'=>0,'msg'=>'导入完成']);
                }catch (\Exception $exception){
                    $transaction->rollBack();
                    return $this->asJson(['code'=>1,'msg'=>'导入失败','data'=>$exception->getMessage()]);
                }

            }
            return $this->asJson(['code'=>1,'msg'=>'未检测到文件内容']);
        } else {
            return $this->asJson(['code'=>0, 'msg'=>'导入失败：文件保存失败', 'data'=>$file->error]);
        }

        return $this->asJson(['code'=>1,'data'=>$file->extension]);
    }

    /**
     * 删除任务
     * @return \yii\web\Response
     */
    public function actionDestroy()
    {
        $id = Yii::$app->request->post('id');
        $call_ids = (new Query())->from('calls')->where(['id_campaign'=>$id])->select(['id'])->indexBy('id')->all($this->callcenter_db);
        $db = $this->callcenter_db;
        $transaction = $db->beginTransaction();
        try{
            //删除call_recording表
            if ($call_ids){
                $id_call_outgoing = array_keys($call_ids);
                $db->createCommand()->delete('call_recording',[
                    'id_call_outgoing' => $id_call_outgoing,
                ])->execute();
            }
            //删除call_progress_log表
            $db->createCommand()->delete('call_progress_log',[
                'id_campaign_outgoing' => $id,
            ])->execute();
            //删除calls表
            $db->createCommand()->delete('calls',[
                'id_campaign' => $id,
            ])->execute();
            //删除campaign_form表
            $db->createCommand()->delete('campaign_form',[
                'id_campaign' => $id,
            ])->execute();
            //删除campaign
            $db->createCommand()->delete('campaign',[
                'id' => $id,
            ])->execute();
            $transaction->commit();
            return $this->asJson(['code'=>0,'msg'=>'删除成功']);
        }catch (\Exception $exception){
            $transaction->rollBack();
            return $this->asJson(['code'=>1,'msg'=>'删除失败','data'=>$exception->getMessage()]);
        }
    }

    /**
     * 获取队列成员数作为最大并发数
     * @return \yii\web\Response
     */
    public function actionGetMaxChannelsByQueue()
    {
        $extension = Yii::$app->request->post('extension');
        if ($extension){
            $count = (new Query())->from('queues_details')->where(['id'=>$extension,'keyword'=>'member'])->count('*',$this->asterisk_db);
            return $this->asJson(['code'=>0,'msg'=>'请求成功','data'=>$count]);
        }
        return $this->asJson(['code'=>1,'msg'=>'参数错误']);
    }

    public function actionCalls($id)
    {
        $campaign = (new Query())->from('campaign')->where(['id'=>$id])->one($this->callcenter_db);
        if ($campaign==false){
            throw new NotFoundHttpException('该任务不存在');
        }
        if (Yii::$app->request->isAjax){
            //当前任务对应的队列的分机成员
            $members = (new Query())->from('queues_details')
                ->where(['id'=>$campaign['queue'],'keyword'=>'member'])
                ->orderBy('flags asc')
                ->all($this->asterisk_db);
            $extens = [];
            foreach ($members as $member){
                if (preg_match('/Local\/(\d+)@from-queue/',$member['data'],$arr)){
                    $time = date('Y-m-d H:i:s');
                    $rs = $this->ami->ExtensionState($arr[1],'from-internal');
                    $extens[$arr[1]] = [
                        'status' => $rs['Status'],
                        'status_name' => Yii::$app->params['extension_status'][$rs['Status']],
                        'update_time' => $time,
                    ];
                }
            }
            return $this->asJson(['code'=>0,'msg'=>'查询成功','data'=>$extens]);
        }
        //呼叫总数
        $total = (new Query())->from('calls')->where(['id_campaign'=>$id])->count('*',$this->callcenter_db);
        //已呼叫数
        $hasCall = (new Query())->from('calls')->where(['and',['=','id_campaign',$id],['<>','status','']])->count('*',$this->callcenter_db);
        //进度
        $percent = $total>0?100*round($hasCall/$total,4).'%':'0%';

        //当前任务对应的队列的分机成员
        $members = (new Query())->from('queues_details')
            ->where(['id'=>$campaign['queue'],'keyword'=>'member'])
            ->orderBy('flags asc')
            ->all($this->asterisk_db);
        $extens = [];
        foreach ($members as $member){
            if (preg_match('/Local\/(\d+)@from-queue/',$member['data'],$arr)){
                $exten_total = (new Query())->from('cdr')->where(['and',['=','dst',$arr[1]],['=','userfield',$id]])->count('*',$this->cdr_db);
                $success = (new Query())->from('cdr')->where(['and',['=','dst',$arr[1]],['=','userfield',$id],['=','disposition','ANSWERED'],['>','billsec',0]])->count('*',$this->cdr_db);
                $times = (new Query())->from('cdr')->where(['and',['=','dst',$arr[1]],['=','userfield',$id],['=','disposition','ANSWERED'],['>','billsec',0]])->sum('billsec',$this->cdr_db);
                $times = $times==null?0:$times;
                $extens[$arr[1]]['total'] = $exten_total;
                $extens[$arr[1]]['success'] = $success;
                $extens[$arr[1]]['percent'] = $exten_total>0?100*round($success/$exten_total,4).'%':'0%';
                $extens[$arr[1]]['times_formate'] = $this->secToTime($times);
                $extens[$arr[1]]['times_avg'] = $exten_total>0?round($times/$exten_total):0;
                $extens[$arr[1]]['times'] = $times;
            }
        }
        //图表数据
        $bar_data = [
            'label' => '"呼叫数","接通数"',
            'xAxis' => implode(',',array_keys($extens)),
        ];
        $bar_total = $bar_success = $bar_times = [];
        foreach ($extens as $k => $v){
            array_push($bar_total,$v['total']);
            array_push($bar_success,$v['success']);
            //array_push($bar_times,$v['times']);
        }
        $bar_data['total'] = implode(',',$bar_total);
        $bar_data['success'] = implode(',',$bar_success);
        //$bar_data['times'] = implode(',',$bar_times);

        //饼状图
        $pie_data = [
            'label' => '"成功","失败"',
            'data' => json_encode([
                [
                    'name'=>'成功',
                    'value'=>(new Query())->from('calls')->where(['id_campaign'=>$id,'status'=>'Abandoned'])->count('*',$this->callcenter_db)
                ],
                [
                    'name'=>'失败',
                    'value'=>(new Query())->from('calls')->where(['id_campaign'=>$id,'status'=>'Failure'])->count('*',$this->callcenter_db)
                ]
            ]),
        ];

        return $this->render('calls',[
            'campaign' => $campaign,
            'total' => $total,
            'hasCall' => $hasCall,
            'percent' => $percent,
            'extens' => $extens,
            'bar_data' => $bar_data,
            'pie_data' => $pie_data,
        ]);
    }

    /**
     * @param $times
     * @return string
     */
    public function secToTime($times){
        $result = '00:00:00';
        if ($times>0) {
            $hour = floor($times/3600);
            $minute = floor(($times-3600 * $hour)/60);
            $second = floor((($times-3600 * $hour) - 60 * $minute) % 60);
            $result = $hour.':'.$minute.':'.$second;
        }
        return $result;
    }

    public function actionConfig()
    {
        $data = (new Query())->from('valor_config')->indexBy('config_key')->all($this->callcenter_db);
        if (Yii::$app->request->isAjax){
            $post = Yii::$app->request->post();
            $transaction = $this->callcenter_db->beginTransaction();
            try{
                foreach ($post as $key=>$val){
                    $this->callcenter_db->createCommand()->update('valor_config',['config_value'=>$val],['config_key'=>'dialer.'.$key])->execute();
                }
                $transaction->commit();
                return $this->asJson(['code'=>0,'msg'=>'更新成功']);
            }catch (\Exception $exception){
                $transaction->rollBack();
                return $this->asJson(['code'=>1,'msg'=>'更新失败']);
            }
        }
        return $this->render('config',['data'=>$data]);
    }

}